package com.woniuxy.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect//表示这个类是一个切面
@Component//表示是一个工具类，需要注册到spring中，才能够直接使用
public class MyAspectAnno {
    //切入点表达式 定义出来
    @Pointcut("execution(* com.woniuxy.service.impl.*.*(..))")
    private void  myPointCut(){}
    /**
     * 前置通知
     * @param joinPoint
     */
    @Before("myPointCut()")
    public void beforeAdvice(JoinPoint joinPoint){
        System.out.println("前置通知start");
        System.out.println("MyAspect.beforeAdvice:前置通知，模拟检查有没有权限……");
        System.out.print("目标类是："+joinPoint.getTarget());
        System.out.println("被增强的目标类的对应的方法是："+joinPoint.getSignature().getName());
        System.out.println("前置通知end");
    }

    /**
     * 后置通知
     * @param joinPoint
     */
    @AfterReturning("myPointCut()")
    public void afterReturnningAdvice(JoinPoint joinPoint){
        System.out.println("后置通知start");
        System.out.print("MyAspect.afterAdvice:后置通知，模拟记录日志……");
        System.out.println("被增强的目标类的对应的方法是："+joinPoint.getSignature().getName());
        System.out.println("后置通知end");
    }

    /**
     * 异常通知
     * @param joinPoint
     * @param e 传入的异常名称
     */
    @AfterThrowing(pointcut = "myPointCut()",throwing = "e")
    public void throwingAdvice(JoinPoint joinPoint,Throwable e){
        System.out.println("异常通知start");
        System.out.println("异常通知：出了什么异常"+e.getMessage());
        System.out.println("异常通知end");
    }

    /**
     * 最终通知
     */
    @After("myPointCut()")
    public void afterAdvice() {
        System.out.println("最终通知start");
        System.out.println("无论目标类成功与否，我都要执行，用来释放资源……");
        System.out.println("最终通知end");
    }

    /**
     *  环绕通知
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("myPointCut()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("变态的环绕通知");
        System.out.println("单纯的环绕通知，方法前通知");
        Object proceed = proceedingJoinPoint.proceed();
        System.out.println("单纯的环绕通知，方法后通知");
        return proceed;
    }
}
